package com.lzj.framework.mvc;

import cn.hutool.core.util.ObjUtil;
import com.lzj.common.annotation.IgnoreRestResponseAdvice;
import com.lzj.common.core.domain.R;
import com.lzj.common.core.page.TableDataInfo;
import com.lzj.common.utils.JsonUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;


/**
 * spring MVC提供的全局响应拦截器 本质上是一个切面
 * 
 * @author 贱贱
 */
@RestControllerAdvice
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {

    /**
     * 判断是否执行beforeBodyWrite
     * @param returnType 控制器方法的返回类型
     * @param converterType 选定的 HttpMessageConverter 类型
     * @return 返回true通过
     */
    @Override
    public boolean supports( MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 被@IgnoreRestResponseAdvice标记 或 返回类型为R.class 的不会被advice处理
        Class<?> controllerClass = returnType.getContainingClass();
        return !(
                // 不在com.lzj包下的不处理
                !controllerClass.getPackage().getName().startsWith("com.lzj")
                //  被@IgnoreRestResponseAdvice标记的方法或类不处理
                || returnType.hasMethodAnnotation(IgnoreRestResponseAdvice.class)
                || controllerClass.isAnnotationPresent(IgnoreRestResponseAdvice.class)
                // 返回值类型为R.class | TableDataInfo.class 的不处理    
                || returnType.getParameterType().isAssignableFrom(R.class) 
                || returnType.getParameterType().isAssignableFrom(TableDataInfo.class) 
        );
    }

    @Override
    public Object beforeBodyWrite(Object body,
                                  MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {
        
        if (ObjUtil.isNull(body)) {
            return R.fail("查询不到数据");
        }
        
        // 如果接口返回类型为void 直接返回200成功
        if (returnType.getParameterType().isAssignableFrom(void.class)){
            return R.ok();
        }
        // 如果接口直接返回String ,响应的Content-Type是text/plain, 要手动修改为application/json
        if (body instanceof String){
            return JsonUtils.toJsonString(R.ok(body));
        }
        // 如果body 类型为 int ,则为操作
        if (body instanceof Integer){
            return (Integer)body > 0 ? R.fail("操作失败: row: 0") : R.ok("操作成功: row: "+ body);
        }
        
        return R.ok(body);
    }
}
